<template>
  <!-- 最外层容器 -->
  <section class="todoapp">
    <!-- 头部 -->
    <section class="header">
      <h1>代办事项</h1>
      <input
        type="text"
        class="new-todo"
        placeholder="添加代办事项"
        @keyup.enter="addTodo"
      />
    </section>
    <!-- 代办列表 -->
    <section class="main">
      <!-- 全选按钮 -->
      <input
        type="checkbox"
        id="toggle-all"
        class="toggle-all"
        v-model="toggleAll"
      />
      <label for="toggle-all">全部完成</label>
      <!-- 代办事项列表 -->
      <ul class="todo-list">
        <li
          class="todo"
          v-for="todo in filteredTodos"
          :key="todo.id"
          :class="{ completed: todo.completed, editing: todo === editedTodo }"
        >
          <div class="view">
            <input type="checkbox" class="toggle" v-model="todo.completed" />
            <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
            <button class="destroy" @click="removeTodo(todo)"></button>
          </div>
          <!-- 编辑框 -->
          <input
            type="text"
            class="edit"
            v-if="editedTodo === todo"
            v-model="todo.title"
            ref="editInputRef"
            @keyup.enter="doneEdit(todo)"
            @blur="doneEdit(todo)"
            @keyup.esc="cancelEdit(todo)"
          />
        </li>
      </ul>
    </section>
    <!-- 底部 -->
    <section class="footer">
      <span class="todo-count"
        ><span>剩余{{ remainNum }}项</span></span
      >
      <ul class="filters">
        <li>
          <a href="#/all" :class="{ selected: visiblity === 'all' }">全部</a>
        </li>
        <li>
          <a href="#/active" :class="{ selected: visiblity === 'active' }"
            >未完成</a
          >
        </li>
        <li>
          <a href="#/completed" :class="{ selected: visiblity === 'completed' }"
            >已完成</a
          >
        </li>
      </ul>
      <button
        class="clear-completed"
        @click="removeCompleted"
        v-show="todos.length > remainNum"
      >
        清除已完成
      </button>
    </section>
  </section>
</template>

<script setup>
import { ref, computed, watchEffect, watch, nextTick } from "vue";

// 每一项的待办事项结构如下
// [{id: 1,title: 'xxx', completed: false}]

const STORAGE_KEY = "todo-list";
// 待办事项mock数据
// const TODO_MOCK = [
//   {
//     id: 1,
//     title: "学习vue3",
//     completed: false,
//   },
//   {
//     id: 2,
//     title: "学习javascript",
//     completed: true,
//   },
//   {
//     id: 3,
//     title: "打游戏",
//     completed: false,
//   },
// ];
// 尝试从本地缓存中获取，如果没有数据则使用空数组(第一次)
const todos = ref(JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]"));
// const todos = ref(TODO_MOCK);
// 默认显示所有待办事项 取值：'all' 'active' 'completed'
const visiblity = ref("all");

const filters = {
  all: (todos) => todos,
  active: (todos) => todos.filter((todo) => !todo.completed),
  completed: (todos) => todos.filter((todo) => todo.completed),
};

const filteredTodos = computed(() => filters[visiblity.value](todos.value));
// 未完成项
const remainNum = computed(() => filters["active"](todos.value).length);
// 全选/取消全选
const toggleAll = ref(false);
// 暂存被编辑的待办项
const editedTodo = ref(null);
// 暂存编辑前的文本
let beforeEditCache = "";
const editInputRef = ref(null);

// 监听hash变化
window.addEventListener("hashchange", onHashChange);
function onHashChange() {
  const route = window.location.hash.replace(/#\//, "");
  if (filters[route]) {
    visiblity.value = route;
  } else {
    window.location.hash = "";
    visiblity.value = "all";
  }
}

function removeTodo(todo) {
  if (window.confirm("确定要删除此待办事项吗?")) {
    todos.value.splice(todos.value.indexOf(todo), 1);
  } else {
    if (beforeEditCache) {
      // 还原
      todo.title = beforeEditCache;
      beforeEditCache = "";
    }
  }
}

function cancelEdit(todo) {
  // 退出编辑模式
  editedTodo.value = null;
  // 还原编辑前的内容
  todo.value = beforeEditCache;
}

function removeCompleted() {
  if (window.confirm("确定要删除所有已完成的待办事项吗?")) {
    todos.value = filters["active"](todos.value);
  }
}

function addTodo(event) {
  // 拿到用户输入的值
  const value = event.target.value.trim();
  if (value) {
    todos.value.push({
      id: Date.now(),
      title: value,
      completed: false,
    });
    event.target.value = "";
  }
}

function editTodo(todo) {
  editedTodo.value = todo;
  beforeEditCache = todo.title;
  // 输入框聚焦
  nextTick(() => {
    editInputRef.value[0].focus();
  });
}

function doneEdit(todo) {
  // 退出编辑模式
  editedTodo.value = null;
  // 如果标题为空，删除此待办项
  if (!todo.title) {
    removeTodo(todo);
  }
}

watch(toggleAll, (newVal) => {
  if (newVal) {
    todos.value.forEach((todo) => {
      todo.completed = true;
    });
  } else {
    todos.value.forEach((todo) => {
      todo.completed = false;
    });
  }
});

// 持久化存储
watchEffect(() => {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(todos.value));
});
</script>

<style scoped>
@import "./assets/todo.css";
</style>
